package com.grq.mis.component;


import cn.hutool.core.lang.Validator;
import com.grq.mis.dao.LoginRecordDao;
import com.grq.mis.dao.PermissionDao;
import com.grq.mis.dao.RoleDao;
import com.grq.mis.dao.UserPermissionDao;
import com.grq.mis.entity.LoginRecord;
import com.grq.mis.entity.Permission;
import com.grq.mis.entity.Role;
import com.grq.mis.model.view.Menu;
import com.grq.mis.redis.RedisDao;
import com.grq.mis.util.IPUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
public class RbacComponent {

    public static final String LOGIN_ERROR_COUNT = "LOGIN:ERROR_COUNT:";

    @Autowired
    private PermissionDao permissionDao;
    @Autowired
    private RoleDao roleDao;
    @Autowired
    private UserPermissionDao userPermissionDao;
    @Autowired
    private LoginRecordDao loginRecordDao;
    @Autowired
    private RedisDao redisDao;

    @Autowired
    private HttpServletRequest request;

    /**
     * 记录登录日志
     *
     * @param username
     * @param client
     * @param isSuccess
     * @param msg
     */
    public void addLoginRecord(String username, String client, boolean isSuccess, String msg) {
        String ip = IPUtils.getIpAddr(request);
        LoginRecord record = new LoginRecord(username, new Date(), client, ip, isSuccess, msg);
        loginRecordDao.insert(record);
    }

    /**
     * 查询账号密码错误次数
     *
     * @param userId
     * @return
     */
    public int getLoginErrorCount(Long userId) {
        String countstr = redisDao.stringGet(LOGIN_ERROR_COUNT + userId);
        int count = 0;
        if (Validator.isEmpty(countstr)) {
            return count;
        }
        try {
            count = Integer.parseInt(countstr);
        } catch (Exception e) {
            return 0;
        }
        return count;
    }

    /**
     * 增加账号登录错误次数
     *
     * @param userId
     * @return
     */
    public void addLoginErrorCount(Long userId) {
        int count = getLoginErrorCount(userId);
        count++;
        redisDao.stringSave(LOGIN_ERROR_COUNT + userId, count + "", 2, TimeUnit.HOURS);
    }

    /**
     * 清除账号登录错误次数
     *
     * @param userId
     * @return
     */
    public void clearLoginErrorCount(Long userId) {
        redisDao.deleteTable(LOGIN_ERROR_COUNT + userId);
    }


    /**
     * 根据用户ID获取用户的权限编码
     *
     * @param userId
     * @return
     */
    public List<String> findPermissionCodeByUserId(long userId) {

        List<String> codes;

        if (userId == 1L) {// 超级管理员帐号
            codes = permissionDao.findAllCode();
            codes.add("*");
        } else {
            codes = userPermissionDao.findUserCode(userId);
        }

        return codes;
    }

    /**
     * 根据用户ID获取用户的角色代码
     *
     * @param userId
     * @return
     */
    public List<String> findRoleCodeByUserId(Long userId) {

        List<String> codes = new ArrayList<>();

        List<Role> roles = roleDao.findByUserId(userId);
        for (Role role : roles) {
            codes.add(role.getCode());
        }
        if (userId == 1L) {
            codes.add("*");
        }

        return codes;
    }

    /**
     * 查询顶级的菜单
     * @param permissions
     * @return
     */
    public List<Menu> findMenusByPermissionCode(Collection<String> permissions) {
        return permissionDao.createLambdaQuery().andEq(Permission::getParentId, 0).andEq(Permission::getIsLink,true).andIn(Permission::getCode, permissions).asc(Permission::getSort).select(Menu.class);
    }


}
